﻿using System;
using System.Reflection;
using System.Collections;
using System.ComponentModel.Design;

namespace SedionFormDesigner.Service
{
    /// <summary>
    ///  在设计期间导入类型
    /// </summary>
    public class SedionTypeResolutionService : ITypeResolutionService
    {
        private Hashtable assemblies;

        public Assembly[] ReferenceAssemblies
        {
            get
            {
                if (assemblies == null)
                    assemblies = new Hashtable();
                Assembly[] result = new Assembly[assemblies.Values.Count];
                assemblies.Values.CopyTo(result, 0);
                return result;
            }
        }

        #region ITypeResolutionService 成员

        public System.Reflection.Assembly GetAssembly(System.Reflection.AssemblyName name, bool throwOnError)
        {
            Assembly assembly = null;
            if (assemblies != null)
                assembly = assemblies[name] as Assembly;

            if ((assembly == null) && throwOnError)
                throw new Exception(String.Concat("Assembly ", name.Name, " not found in referenced assemblies."));

            return assembly;
        }

        public System.Reflection.Assembly GetAssembly(System.Reflection.AssemblyName name)
        {
            return GetAssembly(name, false);
        }

        public string GetPathOfAssembly(System.Reflection.AssemblyName name)
        {
            Assembly assembly = GetAssembly(name, false);
            if (assembly != null)
                return assembly.Location;

            return null;
        }

        public Type GetType(string name, bool throwOnError, bool ignoreCase)
        {
            // 如果是完全合法的名称则可以用此方法获取
            Type type = Type.GetType(name, throwOnError, ignoreCase);

            // 如果没发现,那么在缓存的反射集合中查找
            if ((type == null) && (assemblies != null))
            {
                foreach (Assembly assembly in assemblies.Values)
                {
                    type = assembly.GetType(name, throwOnError, ignoreCase);
                    if (type != null)
                        break;
                }
            }

            // 很不幸,没有发现
            if ((type == null) && throwOnError)
                throw new Exception(String.Concat("The type ", name, " could not be found. ",
                    "If it is an unquanlified name, then its assembly has not been referenced."));

            return type;
        }

        public Type GetType(string name, bool throwOnError)
        {
            return GetType(name, throwOnError, false);
        }

        public Type GetType(string name)
        {
            return GetType(name, false, false);
        }

        /// <summary>
        ///  添加程序集用于反射
        /// </summary>
        public void ReferenceAssembly(System.Reflection.AssemblyName name)
        {
            if (assemblies == null)
                assemblies = new Hashtable();

            if (!assemblies.Contains(name))
                assemblies.Add(name, Assembly.Load(name));
        }

        #endregion
    }
}
